package com.learning.thread.juc.tool;

import java.util.concurrent.Semaphore;

/**
 * ClassName: SemaphorePool
 * Description: Semaphore 实现资源池
 * Date: 2016/11/26 17:45
 *
 * @author SAM SHO
 * @version V1.0
 */
public class SemaphorePool {

    private static final int MAX_AVAILABLE = 100;

    /**
     * 最大可以有 100 个许可
     */
    private final Semaphore available = new Semaphore(MAX_AVAILABLE);


    public Object getItem() throws InterruptedException {
        // 申请一个许可
        // 同时只能申请 100 个线程进入取得可用项，超过100个则需要等待
        //
        available.acquire();
        return getNextAvailableItem();
    }

    public void putItem(Object x) {
        if (markAsUnused(x)) {
            // 释放一个许可证
            available.release();
        }
    }

    /**
     * 存放对象
     */
    Object[] items = new Object[MAX_AVAILABLE];
    Boolean[] used = new Boolean[MAX_AVAILABLE];

    private Object getNextAvailableItem() {

        for (int i = 0; i < MAX_AVAILABLE; i++) {
            // 如果当前项未被使用，则获得它
            if (!used[i]) {
                // 将当前项标记为已经使用
                used[i] = true;
                return items[i];
            }
        }
        return null;
    }

    private synchronized boolean markAsUnused(Object item) {
        for (int i = 0; i < MAX_AVAILABLE; i++) {
            // 找到给定项的索引
            if (item == items[i]) {
                if (used[i]) {
                    // 将给定项标记为未被使用
                    used[i] = false;
                    return true;
                } else {
                    return false;
                }
            }
        }
        return false;
    }

}


